#!/bin/bash
# bkvs - Bash Key Value Store
# Copyright (c) 2011, David Souther

# See bkvs.1 for synopsis and interface.

_BKVS_ROOTDIR=${BKVS_ROOTDIR:='/tmp/bkvs/'}
if [[ $1 = "-r" ]]; then _BKVS_ROOTDIR="$2"; shift 2; fi
_BKVS_ROOTDIR=${_BKVS_ROOTDIR%%/}	#Remove the trailing slash
[[ -d $_BKVS_ROOTDIR ]] || mkdir "$_BKVS_ROOTDIR";

function get() {
	if [[ -f "$1" ]];
	then	#Found the file, so need to return the value
		cat "$1"
	elif [[ -d "$1" ]]
	then	#Found a key node, so return its values
		ls --almost-all "$1"
	else
		return 1
	fi
}

function set() {
	_file=$file
	file=$1
	shift;	#Remove the file path, so everything left is the value.
	if [[ ! -f "$file" ]]
	then # Need to make the directory, then touch the file.
		directory=${file%/[^/]*} #Get the basename of the path (srsly, it works)
		if [[ ! -d $file ]]
		then	# Make sure the directory is ready for the key
			mkdir --parents $directory
		fi
		# Get the file ready.
		touch "$file"
	fi
	if [[ -z "$*" ]]
	then	# No arg on cmdline, use stdin
		cat - >| "$file~" # Pipe stdin to $file
		mv "$file~" "$file" #overwrite the file when done (so get | set works)
	else	#Put the cmdline value in the node.
		echo "$*" >| "$file"
	fi
	file=$_file;
}

function add() {
	_file=$file
	file=$1
	if [[ ! -f "$file" ]]
	then # Need to make the directory, then touch the file.
		set $*	#Pass it off to the set function, we don't want to dup err handl
	else
		shift;	#Remove the file path, so everything left is the value.
		if [[ -z "$*" ]]
		then	# No arg on cmdline, use stdin
			cat - >> "$file" # Pipe stdin to $file
		else	#Put the cmdline value in the node.
			echo "$*" >> "$file"
		fi
	fi
	file=$_file
}

function delete() {
	if [[ -e "$1" ]]
	then	# It exists... but not for long!
		rm -rf "$1"
	fi
}

# No args? No op!
[[ 0 -eq ${#*} ]] && exit 

action=$1 ; shift
file="$_BKVS_ROOTDIR/$1"; shift

#echo $action $file $* #For debugging

$action $file $*
exit $? # In case the function returned abnormally.
